#pragma once
#include <cstring>
#include <cerrno>
#include <string>
#include <iostream>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "BlockQueue.hpp"
#include "Thread.hpp"
#include <unordered_map>

class UdpClient
{
public:
    UdpClient(const std::string &ip, uint16_t port)
        : server_ip_(ip), server_port_(port)
    {
        recv_ = new yui::Thread(std::bind(&UdpClient::RecvMessage, this), "Thread-1");
        send_ = new yui::Thread(std::bind(&UdpClient::SendMessage, this), "Thread-2");
    }
    // 析构
    ~UdpClient()
    {
        // 等待线程退出
        recv_->Stop();
        send_->Stop();

        delete (recv_);
        delete (send_);
    }
    void StratClient()
    {
        sock_ = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock_ == -1)
        {
            perror("socket fail");
            exit(1);
        }
        std::cout << "创建套接字成功" << std::endl;
        bzero(&svr_, sizeof(svr_));
        svr_.sin_family = AF_INET;
        svr_.sin_addr.s_addr = inet_addr(server_ip_.c_str());
        svr_.sin_port = htons(server_port_);
        //
        send_->Start();
        recv_->Start();
        
    }
    void Join() {
        send_->Join();
        recv_->Join();
    }
    void RecvMessage()
    {
        // while(true)
        // {
        //     std::string msg;
        //     std::cout<<"发送消息#";
        //     std::getline(std::cin,msg);
        //     ssize_t n = sendto(sock_,msg.c_str(),msg.size(),0,(const struct sockaddr*)&svr_,sizeof(svr_));
        //     if(n == -1)
        //     {
        //         continue;
        //     }
        // }
        char buff[1024];
        while (true)
        {
            socklen_t len = sizeof(svr_);
            ssize_t n = recvfrom(sock_, buff, sizeof(buff) - 1, 0, (struct sockaddr *)&svr_, &len);
            if (n > 0)
            {
                buff[n] = 0;
            }
            else
            {
                continue;
            }
            std::cout << "客户端发送消息：" << buff << std::endl;
        }
    }
    void SendMessage()
    {
        while (true)
        {
            std::string msg;
            std::cout << "发送消息#";
            std::getline(std::cin, msg);
            ssize_t n = sendto(sock_, msg.c_str(), msg.size(), 0, (const struct sockaddr *)&svr_, sizeof(svr_));
            if (n == -1)
            {
                continue;
            }
        }
    }

private:
    std::string server_ip_;
    uint16_t server_port_;
    int sock_;
    struct sockaddr_in svr_;
    yui::Thread *recv_;
    yui::Thread *send_;
};